#!/usr/bin/env python
# -*- coding:utf8 -*-
# uncompyle6 version 2.15.1
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.10 (default, Jul  1 2017, 13:36:56) 
# [GCC 4.4.6 20110731 (Red Hat 4.4.6-4)]
# Embedded file name: ./appengine/api/utils.py
# Compiled at: 2017-11-16 15:44:28
"""
Tencent is pleased to support the open source community by making 蓝鲸智云(BlueKing) available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

Comman Utils

Copyright © 2012-2017 Tencent BlueKing. All Rights Reserved. 蓝鲸智云 版权所有
"""
import random, json, logging, requests, etcd
from django.conf import settings
import models
from api.constants import ASSIGN_PROD_NUM

def merge_two_dicts(x, y):
    """Given two dicts, merge them into a new dict as a shallow copy."""
    z = x.copy()
    z.update(y)
    return z


def etcd_client():
    """
    Etcd client
    """
    return etcd.Client(settings.ETCD_SERVERS, allow_reconnect=True)


def registry_service(app_code, server_ip, flag=0, mode='test', version='paas'):
    """
    用于向etcd服务注册服务，通知app在server上部署完成，router对接入服务进行reload
    :param  app_code: 应用编码
    :param  flag:  0/1  0: 上线 1: 下线
    :param  server_ip: IP
    :param  mode:  test/prod 正式线/测试线
    :return etcd.EtcdResult
    """
    client = etcd_client()
    app_code = 't%s' % app_code if mode == 'test' else app_code
    key = '/%s/apps/upstreams/%s/%s' % (version, mode, app_code)
    try:
        _value = eval(client.read(key).value)
    except:
        _value = []

    if flag == 0:
        if server_ip in _value:
            return True
        _value.append(server_ip)
    else:
        if server_ip in _value:
            _value.remove(server_ip)
        else:
            return True
    value = list(set(_value))
    value.sort()
    if len(value) == 0:
        try:
            client.delete(key)
        except:
            logging.exception('no key exist:%s' % key)
        finally:
            logging.exception(u'删除key记录:%s' % key)
            return True

    else:
        ip_str = json.dumps(value)
        logging.info(u'注册服务%s %s' % (key, ip_str))
        return client.write(key, ip_str)


def get_category_by_mode_and_version(mode, version):
    """
    获取分类
    :param mode test/prod
    :param version 版本
    Usage::
      >>> get_category_by_mode_and_version('ieod', 'test')
      ieod_test
    """
    if mode == 'test':
        return 'tapp'
    return 'app'


def assign_servers(app_code, mode, version='', policy='random'):
    """
    Assign App Servers for App
    :param app_code: 应用编码
    :param mode: 环境
    :param version: 版本
    :param policy: 策略(random)
    Usage::
      >>> assign_servers('app_tempale', 'test', 'ieod')
      True, 1
      >>> assign_servers('app_tempale', 'test', 'ieod')
      False, 'msg'
    """
    try:
        bk_app = models.BkApp.objects.get(app_code=app_code)
        category = get_category_by_mode_and_version(mode, version)
        count = bk_app.bkserver_set.filter(category=category, is_active=True).count()
        if count == 0:
            bkservers = models.BkServer.objects.filter(category=category, is_active=True)
            servers_count = bkservers.count()
            if servers_count == 0:
                return (False, 'no servers avaliable')
            if mode == 'test':
                random_idx = random.randint(0, servers_count - 1)
                bk_server = bkservers[random_idx]
                models.BkHostingShip.objects.create(bk_app=bk_app, bk_server=bk_server)
                return (
                 True, 1)
            if servers_count >= ASSIGN_PROD_NUM:
                indexes = random.sample(range(servers_count), ASSIGN_PROD_NUM)
            else:
                indexes = [
                 0]
            _is_master = True
            for index in indexes:
                bk_server = bkservers[index]
                models.BkHostingShip.objects.create(bk_app=bk_app, bk_server=bk_server, is_master=_is_master)
                _is_master = False

            return (True, len(indexes))
        else:
            return (True, count)
    except:
        logging.exception('assign servers error')
        return (
         False, 'assign servers error')


def check_rabbitmq(server_info, admin_account):
    """
    """
    try:
        url = 'http://%s:%s/api/overview' % (server_info['server_ip'], server_info['server_port'])
        r = requests.get(url, auth=(admin_account['name'], admin_account['password']))
        if r.status_code == 200:
            return (True, '')
        if r.status_code == 401:
            return (False, u'管理员账户信息有误')
        return (
         False, u'rabbitmq服务异常')
    except Exception as e:
        return (
         False, str(e))


def apply_mq_res(server_info, admin_account, user_account, vhost):
    """
    """
    try:
        headers = {'content-type': 'application/json'}
        app_code = user_account['name']
        rabbitmq_host = 'http://%s:%s' % (server_info['server_ip'], server_info['server_port'])
        auth = (admin_account['name'], admin_account['password'])
        url = '%s/api/vhosts/%s' % (rabbitmq_host, vhost)
        r = requests.put(url=url, headers=headers, auth=auth)
        if r.status_code != 204:
            return (False, u'创建vhost失败')
        url = '%s/api/users/%s' % (rabbitmq_host, app_code)
        user_json = {'password': user_account['password'],'tags': 'management'}
        r = requests.put(url, headers=headers, auth=auth, json=user_json)
        if r.status_code != 204:
            return (False, u'创建账户失败')
        url = '%s/api/permissions/%s/%s' % (rabbitmq_host, vhost, app_code)
        permission_json = {'configure': '.*','write': '.*','read': '.*'}
        r = requests.put(url, headers=headers, auth=auth, json=permission_json)
        if r.status_code != 204:
            return (False, u'vhost授权失败')
        return (True, '')
    except Exception as e:
        return (
         False, str(e))
